package com.yunke.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunke.common.exception.YunkeException;
import com.yunke.dto.notification.YunkeSendNotificationDto;
import com.yunke.entity.*;
import com.yunke.mapper.*;
import com.yunke.service.YunkeNotificationService;
import com.yunke.service.YunkeUserService;
import com.yunke.vo.notification.YunkeNotificationVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 通知Service实现类
 * 
 * @author yunke
 * @since 1.0.0
 */
@Slf4j
@Service
public class YunkeNotificationServiceImpl extends ServiceImpl<YunkeUserNotificationMapper, YunkeUserNotification> 
        implements YunkeNotificationService {

    @Autowired
    private YunkeUserNotificationMapper notificationMapper;

    @Autowired
    private YunkeNotificationTemplateMapper templateMapper;

    @Autowired
    private YunkeUserService userService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> sendNotification(YunkeSendNotificationDto sendDto) {
        log.info("发送通知，接收用户ID：{}，类型：{}", sendDto.getUserId(), sendDto.getNotificationType());

        try {
            // 验证接收用户是否存在
            YunkeUser receiver = userService.getById(sendDto.getUserId());
            if (receiver == null) {
                throw new YunkeException("接收用户不存在");
            }

            // 获取发送者信息
            Long fromUserId = 0L; // 默认系统通知
            if (StpUtil.isLogin()) {
                fromUserId = StpUtil.getLoginIdAsLong();
            }

            // 创建通知
            YunkeUserNotification notification = createNotification(sendDto, fromUserId);
            
            // 保存通知
            this.save(notification);

            // 异步处理通知发送
            processAsyncNotification(notification);

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("notificationId", notification.getId());
            result.put("message", "通知发送成功");

            log.info("通知发送成功，通知ID：{}", notification.getId());
            return result;
        } catch (Exception e) {
            log.error("发送通知失败", e);
            throw new YunkeException("发送通知失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> batchSendNotification(List<Long> userIds, YunkeSendNotificationDto sendDto) {
        log.info("批量发送通知，用户数量：{}，类型：{}", userIds.size(), sendDto.getNotificationType());

        try {
            Long fromUserId = 0L;
            if (StpUtil.isLogin()) {
                fromUserId = StpUtil.getLoginIdAsLong();
            }

            List<YunkeUserNotification> notifications = new ArrayList<>();
            int successCount = 0;
            int failCount = 0;

            for (Long userId : userIds) {
                try {
                    // 验证用户存在
                    YunkeUser receiver = userService.getById(userId);
                    if (receiver == null) {
                        failCount++;
                        continue;
                    }

                    // 创建通知副本
                    YunkeSendNotificationDto dtoClone = cloneSendDto(sendDto);
                    dtoClone.setUserId(userId);
                    
                    YunkeUserNotification notification = createNotification(dtoClone, fromUserId);
                    notifications.add(notification);
                    successCount++;
                } catch (Exception e) {
                    log.warn("为用户{}创建通知失败", userId, e);
                    failCount++;
                }
            }

            // 批量保存
            if (!notifications.isEmpty()) {
                this.saveBatch(notifications);
                
                // 异步处理
                for (YunkeUserNotification notification : notifications) {
                    processAsyncNotification(notification);
                }
            }

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("totalCount", userIds.size());
            result.put("successCount", successCount);
            result.put("failCount", failCount);
            result.put("message", String.format("批量发送完成，成功：%d，失败：%d", successCount, failCount));

            log.info("批量发送通知完成，成功：{}，失败：{}", successCount, failCount);
            return result;
        } catch (Exception e) {
            log.error("批量发送通知失败", e);
            throw new YunkeException("批量发送通知失败：" + e.getMessage());
        }
    }

    @Override
    public Page<YunkeNotificationVo> getMyNotificationList(Long current, Long size, Integer notificationType, Integer isRead) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("获取我的通知列表，用户ID：{}，类型：{}，已读：{}", currentUserId, notificationType, isRead);

        try {
            Page<YunkeUserNotification> page = new Page<>(current, size);
            LambdaQueryWrapper<YunkeUserNotification> wrapper = new LambdaQueryWrapper<>();
            
            wrapper.eq(YunkeUserNotification::getUserId, currentUserId)
                    .eq(YunkeUserNotification::getStatus, 0);
            
            if (notificationType != null) {
                wrapper.eq(YunkeUserNotification::getNotificationType, notificationType);
            }
            
            if (isRead != null) {
                wrapper.eq(YunkeUserNotification::getIsRead, isRead);
            }
            
            wrapper.orderByDesc(YunkeUserNotification::getCreateTime);
            
            Page<YunkeUserNotification> notificationPage = this.page(page, wrapper);
            
            // 转换为VO
            Page<YunkeNotificationVo> result = new Page<>();
            result.setCurrent(notificationPage.getCurrent());
            result.setSize(notificationPage.getSize());
            result.setTotal(notificationPage.getTotal());
            
            List<YunkeNotificationVo> voList = notificationPage.getRecords().stream()
                    .map(this::convertToNotificationVo)
                    .collect(Collectors.toList());
            result.setRecords(voList);
            
            log.info("获取我的通知列表成功，数量：{}", voList.size());
            return result;
        } catch (Exception e) {
            log.error("获取我的通知列表失败", e);
            throw new YunkeException("获取通知列表失败：" + e.getMessage());
        }
    }

    @Override
    public YunkeNotificationVo getNotificationDetail(Long notificationId) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("获取通知详情，通知ID：{}，用户ID：{}", notificationId, currentUserId);

        try {
            YunkeUserNotification notification = this.getById(notificationId);
            if (notification == null || !notification.getUserId().equals(currentUserId)) {
                throw new YunkeException("通知不存在或无权访问");
            }

            YunkeNotificationVo result = convertToNotificationVo(notification);
            
            // 自动标记为已读
            if (notification.getIsRead() == 0) {
                notification.setIsRead(1);
                notification.setReadTime(System.currentTimeMillis());
                notification.setUpdateTime(System.currentTimeMillis());
                this.updateById(notification);
                result.setIsRead(true);
            }

            log.info("获取通知详情成功，通知ID：{}", notificationId);
            return result;
        } catch (Exception e) {
            log.error("获取通知详情失败，通知ID：{}", notificationId, e);
            throw new YunkeException("获取通知详情失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> markAsRead(Long notificationId) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("标记通知为已读，通知ID：{}，用户ID：{}", notificationId, currentUserId);

        try {
            YunkeUserNotification notification = this.getById(notificationId);
            if (notification == null || !notification.getUserId().equals(currentUserId)) {
                throw new YunkeException("通知不存在或无权访问");
            }

            if (notification.getIsRead() == 0) {
                notification.setIsRead(1);
                notification.setReadTime(System.currentTimeMillis());
                notification.setUpdateTime(System.currentTimeMillis());
                this.updateById(notification);
            }

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("message", "标记已读成功");

            log.info("标记通知为已读成功，通知ID：{}", notificationId);
            return result;
        } catch (Exception e) {
            log.error("标记通知为已读失败，通知ID：{}", notificationId, e);
            throw new YunkeException("标记已读失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> batchMarkAsRead(List<Long> notificationIds) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("批量标记为已读，通知数量：{}，用户ID：{}", notificationIds.size(), currentUserId);

        try {
            int count = notificationMapper.batchMarkAsRead(currentUserId, notificationIds);

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("count", count);
            result.put("message", "批量标记已读成功");

            log.info("批量标记为已读成功，更新数量：{}", count);
            return result;
        } catch (Exception e) {
            log.error("批量标记为已读失败", e);
            throw new YunkeException("批量标记已读失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> markAllAsRead(Integer notificationType) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("全部标记为已读，用户ID：{}，类型：{}", currentUserId, notificationType);

        try {
            int count = notificationMapper.markAllAsRead(currentUserId, notificationType);

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("count", count);
            result.put("message", "全部标记已读成功");

            log.info("全部标记为已读成功，更新数量：{}", count);
            return result;
        } catch (Exception e) {
            log.error("全部标记为已读失败", e);
            throw new YunkeException("全部标记已读失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> deleteNotification(Long notificationId) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("删除通知，通知ID：{}，用户ID：{}", notificationId, currentUserId);

        try {
            YunkeUserNotification notification = this.getById(notificationId);
            if (notification == null || !notification.getUserId().equals(currentUserId)) {
                throw new YunkeException("通知不存在或无权删除");
            }

            notification.setStatus(1); // 标记为已删除
            notification.setUpdateTime(System.currentTimeMillis());
            this.updateById(notification);

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("message", "删除通知成功");

            log.info("删除通知成功，通知ID：{}", notificationId);
            return result;
        } catch (Exception e) {
            log.error("删除通知失败，通知ID：{}", notificationId, e);
            throw new YunkeException("删除通知失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> batchDeleteNotification(List<Long> notificationIds) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("批量删除通知，通知数量：{}，用户ID：{}", notificationIds.size(), currentUserId);

        try {
            int count = notificationMapper.batchDelete(currentUserId, notificationIds);

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("count", count);
            result.put("message", "批量删除成功");

            log.info("批量删除通知成功，删除数量：{}", count);
            return result;
        } catch (Exception e) {
            log.error("批量删除通知失败", e);
            throw new YunkeException("批量删除失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> clearNotifications(Integer notificationType) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("清空通知，用户ID：{}，类型：{}", currentUserId, notificationType);

        try {
            int count = notificationMapper.clearNotifications(currentUserId, notificationType);

            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("count", count);
            result.put("message", "清空通知成功");

            log.info("清空通知成功，删除数量：{}", count);
            return result;
        } catch (Exception e) {
            log.error("清空通知失败", e);
            throw new YunkeException("清空通知失败：" + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getUnreadNotificationCount() {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("获取未读消息统计，用户ID：{}", currentUserId);

        try {
            Map<String, Object> statistics = notificationMapper.getUnreadCountByType(currentUserId);
            
            if (statistics == null) {
                statistics = new HashMap<>();
                statistics.put("totalCount", 0);
                statistics.put("systemCount", 0);
                statistics.put("likeCount", 0);
                statistics.put("commentCount", 0);
                statistics.put("followCount", 0);
                statistics.put("messageCount", 0);
                statistics.put("activityCount", 0);
                statistics.put("orderCount", 0);
            }

            log.info("获取未读消息统计成功，总数：{}", statistics.get("totalCount"));
            return statistics;
        } catch (Exception e) {
            log.error("获取未读消息统计失败", e);
            throw new YunkeException("获取未读消息统计失败：" + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getNotificationSettings() {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("获取通知设置，用户ID：{}", currentUserId);

        try {
            // TODO: 从用户设置表获取通知设置
            Map<String, Object> settings = new HashMap<>();
            settings.put("systemNotify", true);
            settings.put("likeNotify", true);
            settings.put("commentNotify", true);
            settings.put("followNotify", true);
            settings.put("messageNotify", true);
            settings.put("activityNotify", true);
            settings.put("orderNotify", true);
            settings.put("soundEnabled", true);
            settings.put("vibrationEnabled", true);
            settings.put("nightModeEnabled", false);

            return settings;
        } catch (Exception e) {
            log.error("获取通知设置失败", e);
            throw new YunkeException("获取通知设置失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> updateNotificationSettings(Map<String, Object> settings) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("更新通知设置，用户ID：{}", currentUserId);

        try {
            // TODO: 保存到用户设置表
            
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("message", "更新通知设置成功");

            log.info("更新通知设置成功，用户ID：{}", currentUserId);
            return result;
        } catch (Exception e) {
            log.error("更新通知设置失败", e);
            throw new YunkeException("更新通知设置失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> sendSystemNotification(YunkeSendNotificationDto sendDto) {
        log.info("发送系统通知");
        
        try {
            sendDto.setFromUserId(0L); // 系统通知
            sendDto.setNotificationType(1); // 系统通知类型
            
            return sendNotification(sendDto);
        } catch (Exception e) {
            log.error("发送系统通知失败", e);
            throw new YunkeException("发送系统通知失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> sendBroadcastNotification(YunkeSendNotificationDto sendDto) {
        log.info("发送广播通知");
        
        try {
            // TODO: 获取所有活跃用户列表
            List<Long> allUserIds = Arrays.asList(1L, 2L, 3L); // 示例用户列表
            
            return batchSendNotification(allUserIds, sendDto);
        } catch (Exception e) {
            log.error("发送广播通知失败", e);
            throw new YunkeException("发送广播通知失败：" + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getNotificationStatistics() {
        log.info("获取通知统计");
        
        try {
            Map<String, Object> statistics = notificationMapper.getNotificationStatistics();
            
            if (statistics == null) {
                statistics = new HashMap<>();
                statistics.put("totalCount", 0);
                statistics.put("todayCount", 0);
                statistics.put("readCount", 0);
                statistics.put("unreadCount", 0);
            }
            
            return statistics;
        } catch (Exception e) {
            log.error("获取通知统计失败", e);
            throw new YunkeException("获取通知统计失败：" + e.getMessage());
        }
    }

    @Override
    @Async
    public void processAsyncNotification(YunkeUserNotification notification) {
        log.info("处理异步通知发送，通知ID：{}", notification.getId());
        
        try {
            // TODO: 根据渠道发送通知
            if (notification.getChannels() != null) {
                int channels = notification.getChannels();
                
                // 站内信（默认已保存）
                if ((channels & 1) != 0) {
                    log.debug("站内信通知已保存");
                }
                
                // 短信通知
                if ((channels & 2) != 0) {
                    sendSmsNotification(notification);
                }
                
                // 邮件通知
                if ((channels & 4) != 0) {
                    sendEmailNotification(notification);
                }
                
                // 推送通知
                if ((channels & 8) != 0) {
                    sendPushNotification(notification);
                }
            }
            
            // 更新发送状态
            notification.setSendStatus(1); // 已发送
            notification.setSendTime(System.currentTimeMillis());
            this.updateById(notification);
            
        } catch (Exception e) {
            log.error("处理异步通知失败，通知ID：{}", notification.getId(), e);
            
            // 更新为发送失败
            notification.setSendStatus(2);
            this.updateById(notification);
        }
    }

    @Override
    public void sendLikeNotification(Long fromUserId, Long toUserId, Integer relatedType, Long relatedId) {
        log.info("发送点赞通知，从用户：{}，到用户：{}，关联类型：{}，关联ID：{}", 
                fromUserId, toUserId, relatedType, relatedId);
        
        try {
            if (fromUserId.equals(toUserId)) {
                return; // 不给自己发通知
            }
            
            YunkeSendNotificationDto sendDto = new YunkeSendNotificationDto();
            sendDto.setUserId(toUserId);
            sendDto.setNotificationType(2); // 点赞通知
            sendDto.setTitle("收到新的赞");
            sendDto.setContent("有人赞了你的内容");
            sendDto.setRelatedType(relatedType);
            sendDto.setRelatedId(relatedId);
            sendDto.setPriority(2);
            sendDto.setChannels(1); // 只发站内信
            
            // 模拟发送者信息
            sendDto.setUserId(toUserId);
            
            YunkeUserNotification notification = createNotification(sendDto, fromUserId);
            this.save(notification);
            
            processAsyncNotification(notification);
            
        } catch (Exception e) {
            log.error("发送点赞通知失败", e);
        }
    }

    @Override
    public void sendCommentNotification(Long fromUserId, Long toUserId, Integer relatedType, Long relatedId, String content) {
        log.info("发送评论通知，从用户：{}，到用户：{}，关联类型：{}，关联ID：{}", 
                fromUserId, toUserId, relatedType, relatedId);
        
        try {
            if (fromUserId.equals(toUserId)) {
                return; // 不给自己发通知
            }
            
            YunkeSendNotificationDto sendDto = new YunkeSendNotificationDto();
            sendDto.setUserId(toUserId);
            sendDto.setNotificationType(3); // 评论通知
            sendDto.setTitle("收到新评论");
            sendDto.setContent("有人评论了你的内容：" + (content.length() > 20 ? content.substring(0, 20) + "..." : content));
            sendDto.setRelatedType(relatedType);
            sendDto.setRelatedId(relatedId);
            sendDto.setPriority(2);
            sendDto.setChannels(1); // 只发站内信
            
            YunkeUserNotification notification = createNotification(sendDto, fromUserId);
            this.save(notification);
            
            processAsyncNotification(notification);
            
        } catch (Exception e) {
            log.error("发送评论通知失败", e);
        }
    }

    @Override
    public void sendFollowNotification(Long fromUserId, Long toUserId) {
        log.info("发送关注通知，从用户：{}，到用户：{}", fromUserId, toUserId);
        
        try {
            if (fromUserId.equals(toUserId)) {
                return; // 不给自己发通知
            }
            
            YunkeSendNotificationDto sendDto = new YunkeSendNotificationDto();
            sendDto.setUserId(toUserId);
            sendDto.setNotificationType(4); // 关注通知
            sendDto.setTitle("新的关注者");
            sendDto.setContent("有人关注了你");
            sendDto.setPriority(2);
            sendDto.setChannels(1); // 只发站内信
            
            YunkeUserNotification notification = createNotification(sendDto, fromUserId);
            this.save(notification);
            
            processAsyncNotification(notification);
            
        } catch (Exception e) {
            log.error("发送关注通知失败", e);
        }
    }

    /**
     * 创建通知对象
     */
    private YunkeUserNotification createNotification(YunkeSendNotificationDto sendDto, Long fromUserId) {
        YunkeUserNotification notification = new YunkeUserNotification();
        
        notification.setUserId(sendDto.getUserId());
        notification.setFromUserId(fromUserId);
        notification.setNotificationType(sendDto.getNotificationType());
        notification.setRelatedType(sendDto.getRelatedType());
        notification.setRelatedId(sendDto.getRelatedId());
        notification.setExtData(sendDto.getExtData());
        notification.setNotifyIcon(sendDto.getNotifyIcon());
        notification.setJumpUrl(sendDto.getJumpUrl());
        notification.setIsRead(0);
        notification.setPriority(sendDto.getPriority() != null ? sendDto.getPriority() : 2);
        notification.setChannels(sendDto.getChannels() != null ? sendDto.getChannels() : 1);
        notification.setSendStatus(0);
        notification.setExpireTime(sendDto.getExpireTime());
        notification.setStatus(0);
        
        long currentTime = System.currentTimeMillis();
        notification.setCreateTime(currentTime);
        notification.setUpdateTime(currentTime);
        
        // 处理标题和内容
        if (StrUtil.isNotBlank(sendDto.getTemplateCode())) {
            // 使用模板生成内容
            processTemplate(notification, sendDto);
        } else {
            // 直接使用提供的内容
            notification.setTitle(sendDto.getTitle());
            notification.setContent(sendDto.getContent());
        }
        
        return notification;
    }

    /**
     * 处理通知模板
     */
    private void processTemplate(YunkeUserNotification notification, YunkeSendNotificationDto sendDto) {
        try {
            // 查询模板
            LambdaQueryWrapper<YunkeNotificationTemplate> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(YunkeNotificationTemplate::getTemplateCode, sendDto.getTemplateCode())
                    .eq(YunkeNotificationTemplate::getIsEnabled, 1)
                    .eq(YunkeNotificationTemplate::getStatus, 0);
            
            YunkeNotificationTemplate template = templateMapper.selectOne(wrapper);
            
            if (template == null) {
                // 模板不存在，使用默认内容
                notification.setTitle(sendDto.getTitle());
                notification.setContent(sendDto.getContent());
                return;
            }
            
            // 替换模板变量
            String title = template.getTitleTemplate();
            String content = template.getContentTemplate();
            
            if (sendDto.getTemplateParams() != null) {
                for (Map.Entry<String, Object> entry : sendDto.getTemplateParams().entrySet()) {
                    String placeholder = "{" + entry.getKey() + "}";
                    String value = String.valueOf(entry.getValue());
                    
                    if (title != null) {
                        title = title.replace(placeholder, value);
                    }
                    if (content != null) {
                        content = content.replace(placeholder, value);
                    }
                }
            }
            
            notification.setTitle(title);
            notification.setContent(content);
            notification.setNotifyIcon(template.getNotifyIcon());
            notification.setPriority(template.getPriority());
            
        } catch (Exception e) {
            log.warn("处理通知模板失败，使用默认内容", e);
            notification.setTitle(sendDto.getTitle());
            notification.setContent(sendDto.getContent());
        }
    }

    /**
     * 转换为通知VO
     */
    private YunkeNotificationVo convertToNotificationVo(YunkeUserNotification notification) {
        YunkeNotificationVo vo = new YunkeNotificationVo();
        BeanUtils.copyProperties(notification, vo);
        
        vo.setNotificationId(notification.getId());
        vo.setIsRead(notification.getIsRead() == 1);
        vo.setNotificationTypeName(getNotificationTypeName(notification.getNotificationType()));
        vo.setPriorityName(getPriorityName(notification.getPriority()));
        vo.setSendStatusName(getSendStatusName(notification.getSendStatus()));
        
        // 格式化时间
        vo.setCreateTimeText(formatTime(notification.getCreateTime()));
        vo.setSendTimeText(formatTime(notification.getSendTime()));
        
        // 检查是否过期
        vo.setIsExpired(notification.getExpireTime() != null && 
                System.currentTimeMillis() > notification.getExpireTime());
        
        // 获取发送者信息
        if (notification.getFromUserId() != null && notification.getFromUserId() > 0) {
            try {
                YunkeUser fromUser = userService.getById(notification.getFromUserId());
                if (fromUser != null) {
                    vo.setFromUserNickname(fromUser.getNickname());
                    vo.setFromUserAvatar(fromUser.getAvatar());
                }
            } catch (Exception e) {
                log.warn("获取发送者信息失败，用户ID：{}", notification.getFromUserId());
            }
        } else {
            vo.setFromUserNickname("系统");
            vo.setFromUserAvatar("");
        }
        
        // 解析扩展数据
        if (StrUtil.isNotBlank(notification.getExtData())) {
            try {
                Map<String, Object> extData = JSONUtil.toBean(notification.getExtData(), Map.class);
                vo.setExtData(extData);
            } catch (Exception e) {
                log.warn("解析扩展数据失败", e);
                vo.setExtData(new HashMap<>());
            }
        } else {
            vo.setExtData(new HashMap<>());
        }
        
        // TODO: 获取关联对象信息
        vo.setRelatedInfo(new HashMap<>());
        
        return vo;
    }

    /**
     * 克隆发送DTO
     */
    private YunkeSendNotificationDto cloneSendDto(YunkeSendNotificationDto original) {
        YunkeSendNotificationDto clone = new YunkeSendNotificationDto();
        BeanUtils.copyProperties(original, clone);
        return clone;
    }

    /**
     * 发送短信通知
     */
    private void sendSmsNotification(YunkeUserNotification notification) {
        log.info("发送短信通知，通知ID：{}", notification.getId());
        // TODO: 集成短信服务
    }

    /**
     * 发送邮件通知
     */
    private void sendEmailNotification(YunkeUserNotification notification) {
        log.info("发送邮件通知，通知ID：{}", notification.getId());
        // TODO: 集成邮件服务
    }

    /**
     * 发送推送通知
     */
    private void sendPushNotification(YunkeUserNotification notification) {
        log.info("发送推送通知，通知ID：{}", notification.getId());
        // TODO: 集成推送服务
    }

    // 工具方法
    private String getNotificationTypeName(Integer type) {
        switch (type) {
            case 1: return "系统通知";
            case 2: return "点赞通知";
            case 3: return "评论通知";
            case 4: return "关注通知";
            case 5: return "私信通知";
            case 6: return "活动通知";
            case 7: return "订单通知";
            default: return "未知";
        }
    }

    private String getPriorityName(Integer priority) {
        switch (priority) {
            case 1: return "低";
            case 2: return "中";
            case 3: return "高";
            default: return "中";
        }
    }

    private String getSendStatusName(Integer status) {
        switch (status) {
            case 0: return "待发送";
            case 1: return "已发送";
            case 2: return "发送失败";
            default: return "未知";
        }
    }

    private String formatTime(Long timestamp) {
        if (timestamp == null) {
            return "";
        }
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return sdf.format(new Date(timestamp));
        } catch (Exception e) {
            return "";
        }
    }
}